<?php

namespace App\Task;

use App\Model\DataBackhaulSetting;
use App\Model\DataPaymentBackhaul;
use App\Model\DataSpread;
use App\Model\DataUserJuliangTokenRel;
use App\Model\Payment;
use GuzzleHttp\Client;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\DbConnection\Db;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;


//#[Crontab(name: "backhaulOrderTask", rule: "*/30 * * * * *", callback: "execute", memo: "回传上报订单'")]
//#[Crontab(name: "backhaulOrderTask", rule: "*/20 * * * * *", callback: "execute", memo: "回传上报订单'")]
class BackhaulOrderTask
{

    public static $test_user = ['21','312'];

    protected LoggerInterface $logger;

    public static $token = '7FE11418980F94B82110648EC0DAFD2B';

    public static $reportUrl = "https://clue.oceanengine.com/outer/wechat/applet/token/1779984845733000";

    public static $starReportUrl = "https://ad.oceanengine.com/track/activate/";
    public function __construct(protected LoggerFactory $loggerFactory)
    {
        $this->logger = $this->loggerFactory->get('log', 'backhaulOrder');
    }

    public function execute()
    {
        $container = ApplicationContext::getContainer();
        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('default');

        $this->logger->info(date('Y-m-d H:i:s') . '------------------------定时获取redis上的数据');
        $this->logger->info('开始获取用户未处理的数据');
        $today_date = date('Y-m-d 0:0:0',time());
        $nowTime = date('Y-m-d H:i:s',time());
        $time = date('Y-m-d H:i:s',time()-7200);
//        return;
        $handleKey = 'backhaul_order_or_or_or_or_or_live_live';
        try {
//            var_dump($redis->keys('protect_*'));
//            var_dump($redis->keys('backhaul_*'));

            $keyData = $redis->get($handleKey);
            if(!empty($keyData)){

                $this->logger->info('存在处理中的订单进程');
                $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取订单进行上报');
                return;
            }else{
                $redis->set($handleKey,1);
            }
            Db::beginTransaction();
            //获取需要处理的订单
            $paymentData = Payment::query()->where(['is_handle' => 'N','is_backhaul' => 'N','type' => 1])->where('pay_time','!=','')->whereBetween('pay_time',[$time,$nowTime])->get();

            if($paymentData->isNotEmpty()) {
                //判断是否
                $this->logger->info('订单的数据为数量为：', [count($paymentData)]);
                $this->logger->info('获取订单所对应的user_id', [count($paymentData)]);
                $errorMeg = [];
                foreach ($paymentData as $paymentDatum) {
                    //查找这个用户的userInfo

                    $userInfo = Db::table('data_user_' . $paymentDatum->applet_id)->where(['id' => $paymentDatum->user_id])->first();
                    $this->logger->info('获取订单的用户user,id为:', [$userInfo->id]);
                    if (!empty($userInfo)) {

                        $this->logger->info('获取订单对应的推广链接,最新的推广链ID:', [$paymentDatum->spread_id]);
                        $spreadInfo = DataSpread::query()->where(['id' => $paymentDatum->spread_id])->first();

                        if (!empty($spreadInfo)) {
                            $this->logger->info('获取推广链接对应的回传配置', [$spreadInfo->backhaul_setting_id]);
                            $user_type = $spreadInfo->user_type;
                            //判断星图的平台 20240116的新增逻辑
                            $spread_platform = $spreadInfo->spread_platform_id;
                            $this->logger->info('投放的平台为:', [$spread_platform]);
                            $backhaulsettingInfo = DataBackhaulSetting::query()->where(['id' => $spreadInfo->backhaul_setting_id])->first();
                            if (!empty($backhaulsettingInfo)) {
                                //普通用户 头条平台
                                if($spread_platform == 1){
                                    //2024-01-17 新逻辑，新增根据维度回传 不判断是否有计划ID
                                    if($backhaulsettingInfo->backhaul_dimension == 2){

                                        if(!empty($userInfo->clue_token) && $userInfo->clue_token != 'undefined') {
                                            //先获取订单的推广链接ID
                                            $this->logger->info('获取订单所对应的推广最新的回传token', [$userInfo->id]);
                                            $this->handOrder($redis, $paymentDatum, $userInfo, $spreadInfo, $backhaulsettingInfo);
                                        } else {
                                            $paymentDatum->is_handle = 'Y';
                                            $paymentDatum->save();
                                            $this->logger->error('用户没有对应的回传token不正常', [$paymentDatum->id]);
                                            $errorMeg[] = [
                                                'payment_id' => $paymentDatum->id,
                                                'created_at' => date('Y-m-d H:i:s', time()),
                                                'errorMsg' => '用户没有对应的回传token不正常'
                                            ];
                                        }
                                    }else{

                                        if(empty($paymentDatum->ad_id) && empty($userInfo->ad_id)){
                                            $this->logger->info('用户和订单都没有计划ID,id为:', [$paymentDatum->id,$userInfo->id]);
                                            $errorMeg[] = [
                                                'payment_id' => $paymentDatum->id,
                                                'created_at' => date('Y-m-d H:i:s',time()),
                                                'errorMsg' => '用户和订单都没有计划ID'
                                            ];
                                            $paymentDatum->is_handle = 'Y';
                                            $paymentDatum->save();
                                            continue;
                                        }

                                        if(!empty($userInfo->clue_token) && !empty($userInfo->ad_id)) {
                                            if ($userInfo->clue_token != 'undefined') {
                                                //先获取订单的推广链接ID
                                                $this->logger->info('获取订单所对应的推广最新的回传token', [$userInfo->id]);
                                                $this->handOrder($redis, $paymentDatum, $userInfo, $spreadInfo, $backhaulsettingInfo);

                                            } else {
                                                $paymentDatum->is_handle = 'Y';
                                                $paymentDatum->save();
                                                $this->logger->error('用户没有对应的回传token不正常', [$paymentDatum->id]);
                                                $errorMeg[] = [
                                                    'payment_id' => $paymentDatum->id,
                                                    'created_at' => date('Y-m-d H:i:s', time()),
                                                    'errorMsg' => '用户没有对应的回传token不正常'
                                                ];
                                            }
                                        } else {
                                            $paymentDatum->is_handle = 'Y';
                                            $paymentDatum->save();
                                            $this->logger->error('用户没有对应的回传token,ad_id', [$paymentDatum->id]);
                                            $errorMeg[] = [
                                                'payment_id' => $paymentDatum->id,
                                                'created_at' => date('Y-m-d H:i:s', time()),
                                                'errorMsg' => '用户没有对应的回传token,ad_id,click_id'
                                            ];
                                        }
                                    }


                                    //星图用户
                                }else if($spread_platform == 2){

                                    if(!empty($userInfo->click_id) && $userInfo->click_id != 'undefined') {
                                        //先获取订单的推广链接ID
                                        $this->logger->info('获取订单所对应的推广最新的回传token', [$userInfo->id]);
                                        $this->handOrder($redis, $paymentDatum, $userInfo, $spreadInfo, $backhaulsettingInfo);

                                    }else{
                                        $paymentDatum->is_handle = 'Y';
                                        $paymentDatum->save();
                                        $this->logger->error('星图用户没有对应的回传click_id', [$paymentDatum->id]);
                                        $errorMeg[] = [
                                            'payment_id' => $paymentDatum->id,
                                            'created_at' => date('Y-m-d H:i:s', time()),
                                            'errorMsg' => '星图用户没有对应的回传,click_id'
                                        ];
                                    }
                                }

                            } else {
                                $paymentDatum->is_handle = 'Y';
                                $paymentDatum->save();
                                $this->logger->error('推广链接不存在对应的回传配置', [$paymentDatum->id]);
                                $errorMeg[] = [
                                    'payment_id' => $paymentDatum->id,
                                    'created_at' => date('Y-m-d H:i:s', time()),
                                    'errorMsg' => '推广链接不存在对应的回传配置'
                                ];
                            }

                        } else {
                            $paymentDatum->is_handle = 'Y';
                            $paymentDatum->save();
                            $this->logger->error('订单不存在推广链接ID', [$paymentDatum->id]);
                            $errorMeg[] = [
                                'payment_id' => $paymentDatum->id,
                                'created_at' => date('Y-m-d H:i:s',time()),
                                'errorMsg' => '订单不存在推广链接ID'
                            ];
                        }
                    } else {
                        $paymentDatum->is_handle = 'Y';
                        $paymentDatum->save();
                        $this->logger->error('订单不存在用户', [$paymentDatum->id]);
                        $errorMeg[] = [
                            'payment_id' => $paymentDatum->id,
                            'errorMsg' => '订单不存在用户',
                            'created_at' => date('Y-m-d H:i:s',time())
                        ];
                    }
                }

                if(!empty($errorMeg)){
                    Db::table('data_payment_backhaul_error')->insert($errorMeg);
                }
            }else{
                $this->logger->info('没有订单需要上报');
            }

            $redis->del($handleKey);
            Db::commit();
        }catch (\Exception $e){
            $redis->del($handleKey);
            $this->logger->error('请求回传|错误：' . $e->getLine() . '|' . $e->getMessage());
            Db::rollBack();
        }
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取订单进行上报');
    }

    public function handOrder($redis,$paymentDatum,$userInfo,$spreadInfo,$backhaulsettingInfo){

        $this->logger->info('处理订单中的回传逻辑:',[$paymentDatum->id]);
        $backhaul_dimension = $backhaulsettingInfo->backhaul_dimension;
        $this->logger->info('回传配置为:',[$backhaulsettingInfo->id]);
        $this->logger->info('回传配置为维度:',[$backhaul_dimension]);

        $this->logger->info('上报类型 1:自定义上报 2：全量上报:',[$backhaulsettingInfo->order_property]);
        //保护Key
        if($backhaul_dimension == 2){
            $protectheadKey = 'protect_'.$spreadInfo->id.'_'.$userInfo->applet_id.'_'.$backhaulsettingInfo->id;
        }else{
            $protectheadKey = 'protect_'.$spreadInfo->id.'_'.$userInfo->applet_id.'_'.$userInfo->ad_id.'_'.$backhaulsettingInfo->id;
        }
        $protectkey =  $protectheadKey.'_'.$backhaulsettingInfo->start_protect;
        //上报类型 1:自定义上报 2：全量上报
        if($backhaulsettingInfo->report_type == 1){
            //上报类型 1:自定义上报 2：全量上报
            $this->logger->info('自定义上报:',[$userInfo->id,$paymentDatum->id]);
            //先判断最低上传金额
            $minimun_report_amount = $backhaulsettingInfo->minimun_report_amount*100;
            $payment_amount = $paymentDatum->amount;
            $this->logger->info('先判断最低上传金额 最后上报金额为:',[$minimun_report_amount]);
            $this->logger->info('订单金额为 单位为分:',[$payment_amount]);

            if($payment_amount > $minimun_report_amount){

                //先判断启动保护 start_protect 前几单必回传
                $this->logger->info('保护回传 保护订单数:',[$backhaulsettingInfo->start_protect]);
                if($redis->exists($protectkey) == 0){

                    $old_key = $redis->keys($protectheadKey.'*');
                    if(!empty($old_key)){
                        $redis->del($old_key);
                    }

                    $countBackhaulCount = 0;
                    $redis->set($protectkey,0);
                }else{
                    $countBackhaulCount = $redis->get($protectkey);
                }
                $this->logger->info('统计此用户用了此推广链接回传了多少单:',[$countBackhaulCount]);

                //先判断回传配置是否需要保护
                if($countBackhaulCount < $backhaulsettingInfo->start_protect && $backhaulsettingInfo->start_protect != 0) {
                    //先判断回传配置的染色时间当天自然日还是24小时
                    $dyeing_time = $userInfo->dyeing_time;
                    //24小时
                    if ($backhaulsettingInfo->backhaul_type == 1 || $backhaulsettingInfo->backhaul_type == 3) {
                        $check_first_time = date('Y-m-d H:i:s', strtotime($dyeing_time) + 86400);
                    }
                    //当天
                    if ($backhaulsettingInfo->backhaul_type == 2 || $backhaulsettingInfo->backhaul_type == 4) {
                        $check_first_time = date('Y-m-d 23:59:59', strtotime($dyeing_time));
                    }
                    //判断是不是首充
                    $protectQuery = Payment::query()
                        ->where('user_id', $paymentDatum->user_id)
                        ->where('applet_id', $paymentDatum->applet_id)
                        ->where('spread_id', $spreadInfo->id);
                    if($backhaul_dimension == 1){
                        $protectQuery->where('ad_id', $paymentDatum->ad_id);
                    }
                    $firstCount = $protectQuery->where('status', 2)
                        ->where('pay_time', '<', $paymentDatum->pay_time)
                        ->count('id');
                    $is_today = $this->todayOrder($paymentDatum, $dyeing_time, $check_first_time);
                    if ($firstCount == 0 && $is_today) {
                        $this->logger->info('首充订单保护回传:', [$paymentDatum->id]);
                        $uploadData = $this->uploadPayment($userInfo, $paymentDatum, $spreadInfo);
                        if ($uploadData) {
                            $redis->set($protectkey, $countBackhaulCount + 1);
                            $this->installRel($userInfo, $paymentDatum, $backhaulsettingInfo, 3, $protectkey,2,$countBackhaulCount + 1);
                            $paymentDatum->is_backhaul = 'Y';
                            $paymentDatum->is_handle = 'Y';
                            $paymentDatum->save();
                        }
                        return true;
                    }else{
                        $this->logger->info('此单不是首充订单:', [$paymentDatum->id]);
                    }
                }


//                if($countBackhaulCount >= $backhaulsettingInfo->start_protect || $backhaulsettingInfo->start_protect == 0){
                    $this->logger->info('走充值流程:', [$paymentDatum->id]);
                    $backhaul_filterate_num = $backhaulsettingInfo->backhaul_filterate_num;
                    $backhaul_filterate_miss = $backhaulsettingInfo->backhaul_filterate_miss;
                    //2024-03-12 新增先扣单再回传
                    $reversal_mode = $backhaulsettingInfo->reversal_mode;
                    $this->logger->info('查看回传配置是否开启先扣再传:', [$reversal_mode]);
                    if($backhaul_filterate_num == 0 && $backhaul_filterate_miss == 0) {

                        $this->logger->info('订单回传规则 每几单漏几单都为0，此订单不回传:',[$backhaul_filterate_num,$backhaul_filterate_miss]);
                        $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,10);
                        $paymentDatum->is_handle = 'Y';
                        $paymentDatum->save();

                    }else{
                        //判断回传过滤逻辑 每几单，漏几单
                        $this->logger->info('判断回传过滤逻辑 每几单，漏几单:',[$backhaul_filterate_num,$backhaul_filterate_miss]);
                        //设计redis的回传逻辑 //判断逻辑是否存在
                        if($backhaul_dimension == 2){
                            $backhaul_head_key = 'backhaul_'.$spreadInfo->id.'_'.$userInfo->applet_id.'_'.$backhaulsettingInfo->id;
                        }else{
                            $backhaul_head_key = 'backhaul_'.$spreadInfo->id.'_'.$userInfo->applet_id.'_'.$userInfo->ad_id;
                        }
                        $backhaul_key = $backhaul_head_key.'_'.$backhaul_filterate_num.'_'.$backhaul_filterate_miss;
                        if($redis->exists($backhaul_key) == 0){
                            //删除之前属于此用户的回传key
                            $old_key = $redis->keys($backhaul_head_key.'*');
                            if(!empty($old_key)){
                                $redis->del($old_key);
                            }
                            $redis->hSet($backhaul_key,'backhaul_filterate_num',$backhaul_filterate_num);
                            $redis->hSet($backhaul_key,'backhaul_filterate_miss',$backhaul_filterate_miss);
                            //20240312 新增一个参数，判断是先传后扣，还是先扣后传
                            $redis->hSet($backhaul_key,'reversal_mode',$reversal_mode);
                        }
                        $redis_reversal_mode = $redis->hGet($backhaul_key,'reversal_mode');
                        //20240312 新增一个参数，判断是先传后扣，还是先扣后传
                        if(empty($redis_reversal_mode)) {
                            $this->logger->info('没有先扣再传设置,重新设置',[$redis_reversal_mode]);
                            $redis->hSet($backhaul_key, 'reversal_mode', $reversal_mode);
                        }else{
                            //判断此参数是否修改过,如果修改过，需要重新设置参数
                            $this->logger->info('判断此参数是否修改过,如果修改过，需要重新设置参数',[$redis_reversal_mode,$reversal_mode]);
                            if($redis_reversal_mode != $reversal_mode){
                                $this->logger->info('回传顺序发生，需要重新设置参数',[$redis_reversal_mode,$reversal_mode]);
                                $redis->hSet($backhaul_key,'backhaul_filterate_num',$backhaul_filterate_num);
                                $redis->hSet($backhaul_key,'backhaul_filterate_miss',$backhaul_filterate_miss);
                                $redis->hSet($backhaul_key,'reversal_mode',$reversal_mode);

                            }
                        }

                        $redis_reversal_mode = $redis->hGet($backhaul_key,'reversal_mode');
                        $redis_backhaul_num = $redis->hGet($backhaul_key,'backhaul_filterate_num');
                        $redis_backhaul_miss = $redis->hGet($backhaul_key,'backhaul_filterate_miss');

                        if(intval($redis_backhaul_miss) == 0 && intval($redis_backhaul_num) == 0){
                            $this->logger->info('漏单和上传订单都为0时，重新设置回传规则',[$paymentDatum->id]);
                            $redis->hSet($backhaul_key,'backhaul_filterate_num',$backhaul_filterate_num);
                            $redis->hSet($backhaul_key,'backhaul_filterate_miss',$backhaul_filterate_miss);
                            $redis_backhaul_num = $backhaul_filterate_num;
                            $redis_backhaul_miss = $backhaul_filterate_miss;
                        }

                        if($redis_reversal_mode == 1){

                            if($redis_backhaul_num != 0) {
                                //2024 03-08 新增
                                $this->backhaulOrder($redis,$paymentDatum,$userInfo,$backhaulsettingInfo,$spreadInfo,$backhaul_dimension,$backhaul_key,$redis_backhaul_num,$backhaul_filterate_num);
                            }else{
                                if($redis_backhaul_miss != 0){
                                    //2024 03-08 新增
                                    $this->notBackhaulOrder($redis,$paymentDatum,$userInfo,$backhaulsettingInfo,$spreadInfo,$backhaul_dimension,$backhaul_key,$redis_backhaul_miss,$backhaul_filterate_miss);
                                }
                            }
                        }else{
                            if($redis_backhaul_miss != 0){
                                //2024 03-08 新增
                                $this->notBackhaulOrder($redis,$paymentDatum,$userInfo,$backhaulsettingInfo,$spreadInfo,$backhaul_dimension,$backhaul_key,$redis_backhaul_miss,$backhaul_filterate_miss);
                            }elseif($redis_backhaul_num != 0) {
                                //2024 03-08 新增
                                $this->backhaulOrder($redis,$paymentDatum,$userInfo,$backhaulsettingInfo,$spreadInfo,$backhaul_dimension,$backhaul_key,$redis_backhaul_num,$backhaul_filterate_num);
                            }
                        }
                    }
//                    else{
//
//                        //判断每几单不为0的情况下，属于全量上报
//                        if($backhaul_filterate_num != 0 && $backhaul_filterate_miss == 0){
//                            $this->logger->info('判断每几单不为0的情况下，属于全量上报:',[$paymentDatum->id]);
//                            $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
//                            if($uploadData) {
//
//                                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,12);
//                                $paymentDatum->is_backhaul = 'Y';
//                                $paymentDatum->is_handle = 'Y';
//                                $paymentDatum->save();
//                            }
//                        }else{
//
//
//
//                    }
//                }else{
//                    $this->logger->info('订单保护回传:',[$paymentDatum->id]);
//                    $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
//                    if($uploadData) {
//                        $redis->set($protectkey,$countBackhaulCount+1);
//                        $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,3,$protectkey);
//                        $paymentDatum->is_backhaul = 'Y';
//                        $paymentDatum->is_handle = 'Y';
//                        $paymentDatum->save();
//                    }
//                }
            }else{
                $this->logger->info('订单金额为 不够回传条件:',[$paymentDatum->id]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,2);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }
        }else{
            $this->logger->info('全量上报:',[$userInfo->id,$paymentDatum->id]);
            $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
            //删除保护Key
            $redis->del($protectkey);
            if($uploadData){
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,1);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->is_backhaul = 'Y';
                $paymentDatum->save();
            }
        }

    }


    //2024-03-08 整合回传信息
    public function backhaulOrder($redis,$paymentDatum,$userInfo,$backhaulsettingInfo,$spreadInfo,$backhaul_dimension,$backhaul_key,$redis_backhaul_num,$backhaul_filterate_num){
        $this->logger->info('此单为需要回传订单:', [$paymentDatum->id]);
        $this->logger->info('查看回传配置:', [$paymentDatum->id]);
        //回传设置
        //1.回传用户在关注后24小时内的所有首充
        //2.回传用户在关注当天自然日的所有首充
        //3.回传用户在关注后24小时内的所有充值
        //4.回传用户在关注当天自然日的所有充值
        $dyeing_time = $userInfo->dyeing_time;
        $day_time = date('Y-m-d H:i:s',strtotime($dyeing_time)+86400);
        $todayNight_time = date('Y-m-d 23:59:59',strtotime($dyeing_time));
        $pay_time = $paymentDatum->pay_time;
        $this->logger->info('用户染色时间为:', [$userInfo->dyeing_time]);
        $this->logger->info('用户支付时间为:', [$paymentDatum->pay_time]);

        if($backhaulsettingInfo->backhaul_type == 1){
            $this->logger->info('回传用户在关注后24小时内的所有首充:', [$paymentDatum->id]);
            //判断是不是首充
            $countQuery = Payment::query()
                ->where('user_id',$paymentDatum->user_id)
                ->where('applet_id',$paymentDatum->applet_id)
                ->where('status',2)
                ->where('spread_id',$spreadInfo->id);
            if($backhaul_dimension == 1){
                $countQuery->where('ad_id',$paymentDatum->ad_id);
            }
            $count= $countQuery->where('pay_time','<',$paymentDatum->pay_time)
                //                                    ->whereBetween('pay_time',[$dyeing_time,$day_time])
                //                                    ->where('id','!=',$paymentDatum->id)
                ->count();
            $is_today = $this->todayOrder($paymentDatum,$dyeing_time,$day_time);
            if($count  == 0 && $is_today) {
                $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
                if($uploadData){
                    $this->logger->info('上报回传成功:', [$paymentDatum->id]);
                    $this->logger->info('上报回传 上报单为:', [$redis_backhaul_num]);
                    $this->logger->info('此订单上报回传,减少redis中的值',[$paymentDatum->id]);
                    $redis->hIncrBy($backhaul_key,'backhaul_filterate_num',-1);
                    $execution_num = $backhaul_filterate_num -$redis_backhaul_num;
                    $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,8,$backhaul_key,2,intval($execution_num+1));
                    $paymentDatum->is_handle = 'Y';
                    $paymentDatum->is_backhaul = 'Y';
                    $paymentDatum->save();
                }
            }else{
                $this->logger->info('订单已经不是首充 不回传:', [$paymentDatum->id]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,9,$backhaul_key);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }

        }else if($backhaulsettingInfo->backhaul_type == 2){
            $this->logger->info('回传用户在关注当天自然日的所有首充:', [$paymentDatum->id]);
            $countQuery = Payment::query()
                ->where('user_id',$paymentDatum->user_id)
                ->where('applet_id',$paymentDatum->applet_id)
                ->where('status',2)
                ->where('spread_id',$spreadInfo->id);
            if($backhaul_dimension == 1){
                $countQuery->where('ad_id',$paymentDatum->ad_id);
            }
            $count= $countQuery->where('pay_time','<',$paymentDatum->pay_time)
                //                                    ->whereBetween('pay_time',[$dyeing_time,$todayNight_time])
                //                                    ->where('id','!=',$paymentDatum->id)
                ->count();
            $this->logger->info('订单数量为:', [$count]);
            $is_today = $this->todayOrder($paymentDatum,$dyeing_time,$todayNight_time);
            if($count  == 0 && $is_today) {
                $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
                if($uploadData){
                    $this->logger->info('上报回传成功:', [$paymentDatum->id]);
                    $this->logger->info('上报回传 上报单为:', [$redis_backhaul_num]);
                    $this->logger->info('此订单上报回传,减少redis中的值',[$paymentDatum->id]);
                    $redis->hIncrBy($backhaul_key,'backhaul_filterate_num',-1);
                    $execution_num = $backhaul_filterate_num - $redis_backhaul_num;
                    $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,7,$backhaul_key,2,intval($execution_num+1));
                    $paymentDatum->is_handle = 'Y';
                    $paymentDatum->is_backhaul = 'Y';
                    $paymentDatum->save();
                }
            }else{
                $this->logger->info('订单已经不是首充 不回传:', [$paymentDatum->id]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,9,$backhaul_key);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }

        }elseif($backhaulsettingInfo->backhaul_type == 3){
            $this->logger->info('回传用户在关注后24小时内的所有充值:', [$paymentDatum->id]);
            $is_today = $this->todayOrder($paymentDatum,$dyeing_time,$day_time);
            if($day_time > $dyeing_time && $is_today){
                $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
                if($uploadData){
                    $this->logger->info('上报回传成功:', [$paymentDatum->id]);
                    $this->logger->info('上报回传 上报单为:', [$redis_backhaul_num]);
                    $this->logger->info('此订单上报回传,减少redis中的值',[$paymentDatum->id]);
                    $redis->hIncrBy($backhaul_key,'backhaul_filterate_num',-1);
                    $execution_num = $backhaul_filterate_num - $redis_backhaul_num;
                    $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,6,$backhaul_key,3,intval($execution_num+1));
                    $paymentDatum->is_handle = 'Y';
                    $paymentDatum->is_backhaul = 'Y';
                    $paymentDatum->save();
                }
            }else{
                $this->logger->info('时间已经超过设置时间:', [$paymentDatum->id,$backhaulsettingInfo->backhaul_type]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,13);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }
        }elseif($backhaulsettingInfo->backhaul_type == 4){
            $this->logger->info('回传用户在关注当天自然日的所有充值:', [$paymentDatum->id]);
            $is_today = $this->todayOrder($paymentDatum,$dyeing_time,$todayNight_time);
            if($todayNight_time > $dyeing_time && $is_today){
                $uploadData = $this->uploadPayment($userInfo,$paymentDatum,$spreadInfo);
                if($uploadData){
                    $this->logger->info('上报回传:', [$paymentDatum->id]);
                    $this->logger->info('上报回传 上报单为:', [$redis_backhaul_num]);
                    $redis->hIncrBy($backhaul_key,'backhaul_filterate_num',-1);
                    $execution_num = $backhaul_filterate_num - $redis_backhaul_num;
                    $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,5,$backhaul_key,3,intval($execution_num+1));
                    $paymentDatum->is_handle = 'Y';
                    $paymentDatum->is_backhaul = 'Y';
                    $paymentDatum->save();
                }
            }else{
                $this->logger->info('时间已经超过设置时间:', [$paymentDatum->id,$backhaulsettingInfo->backhaul_type]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,13);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }
        }
    }


    //2024-03-08 整合扣单信息
    public function notBackhaulOrder($redis,$paymentDatum,$userInfo,$backhaulsettingInfo,$spreadInfo,$backhaul_dimension,$backhaul_key,$redis_backhaul_miss,$backhaul_filterate_miss){
        $dyeing_time = $userInfo->dyeing_time;
        $day_time = date('Y-m-d H:i:s',strtotime($dyeing_time)+86400);
        $todayNight_time = date('Y-m-d 23:59:59',strtotime($dyeing_time));
        if($backhaulsettingInfo->backhaul_type == 1 || $backhaulsettingInfo->backhaul_type == 2) {
            $this->logger->info('漏单判断是不是首充:', [$paymentDatum->id]);
            //判断是不是首充
            $countQuery = Payment::query()
                ->where('user_id', $paymentDatum->user_id)
                ->where('applet_id', $paymentDatum->applet_id)
                ->where('status', 2)
                ->where('spread_id', $spreadInfo->id);
            if ($backhaul_dimension == 1) {
                $countQuery->where('ad_id', $paymentDatum->ad_id);
            }
            $count = $countQuery->where('pay_time', '<', $paymentDatum->pay_time)->count();
            if($backhaulsettingInfo->backhaul_type == 1){
                $is_today = $this->todayOrder($paymentDatum, $dyeing_time, $day_time);
            }else{
                $is_today = $this->todayOrder($paymentDatum, $dyeing_time, $todayNight_time);
            }
            if ($count == 0 && $is_today) {
                $this->logger->info('此订单为漏单，不上报回传,减少redis中的值',[$paymentDatum->id]);
                $num = $redis_backhaul_miss-1;
                $redis->hSet($backhaul_key,'backhaul_filterate_miss',intval($num));
                $this->logger->info('此订单为漏单，不上报回传',[$redis->hGet($backhaul_key,'backhaul_filterate_miss')]);
                $execution_num = $backhaul_filterate_miss - $num;
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,4,$backhaul_key,1,intval($execution_num));
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }else{
                $this->logger->info('漏单订单已经不是首充 不回传:', [$paymentDatum->id]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,9,$backhaul_key);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }
        }elseif($backhaulsettingInfo->backhaul_type == 3) {
            $this->logger->info('回传用户在关注后24小时内的所有充值:', [$paymentDatum->id]);
            $is_today = $this->todayOrder($paymentDatum, $dyeing_time, $day_time);
            if ($day_time > $dyeing_time && $is_today) {
                $this->logger->info('此订单为漏单，不上报回传,减少redis中的值',[$paymentDatum->id]);
                $num = $redis_backhaul_miss-1;
                $redis->hSet($backhaul_key,'backhaul_filterate_miss',intval($num));
                $this->logger->info('此订单为漏单，不上报回传',[$redis->hGet($backhaul_key,'backhaul_filterate_miss')]);
                $execution_num = $backhaul_filterate_miss - $num;
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,4,$backhaul_key,1,intval($execution_num));
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }else{
                $this->logger->info('漏单,时间已经超过设置时间:', [$paymentDatum->id,$backhaulsettingInfo->backhaul_type]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,13);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }
        }elseif($backhaulsettingInfo->backhaul_type == 4) {
            $this->logger->info('回传用户在关注当天自然日的所有充值:', [$paymentDatum->id]);
            $is_today = $this->todayOrder($paymentDatum, $dyeing_time, $todayNight_time);
            if ($todayNight_time > $dyeing_time && $is_today) {
                $this->logger->info('此订单为漏单，不上报回传,减少redis中的值',[$paymentDatum->id]);
                $num = $redis_backhaul_miss-1;
                $redis->hSet($backhaul_key,'backhaul_filterate_miss',intval($num));
                $this->logger->info('此订单为漏单，不上报回传',[$redis->hGet($backhaul_key,'backhaul_filterate_miss')]);
                $execution_num = $backhaul_filterate_miss - $num;
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,4,$backhaul_key,1,intval($execution_num));
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }else{
                $this->logger->info('漏单,时间已经超过设置时间:', [$paymentDatum->id,$backhaulsettingInfo->backhaul_type]);
                $this->installRel($userInfo,$paymentDatum,$backhaulsettingInfo,13);
                $paymentDatum->is_handle = 'Y';
                $paymentDatum->save();
            }
        }
    }

    //判断订单是否今日订单
    public  function todayOrder($paymentInfo,$startTime,$endTime){
        //根据支付时间，判断是否今日订单
        $pay_time = $paymentInfo->pay_time;
        if($pay_time <  $endTime && $pay_time > $startTime){
            return true;
        }
        return false;
    }


    public function installRel($userInfo,$paymentInfo,$backhaulsettingInfo,$type=1,$redis_key='',$is_first=1,$execution_num=0){

        DataPaymentBackhaul::create([
            'user_id' => $userInfo->id,
            'applet_id' => $paymentInfo->applet_id,
            'payment_id' => $paymentInfo->id,
            'xc_open_id' => $userInfo->xc_open_id,
            'clue_token' => $userInfo->clue_token,
            'ad_id' => $userInfo->ad_id,
            'type' => $type,
            'backhaul_setting_id' => $backhaulsettingInfo->id,
            'reids_key' => $redis_key,
            'spread_id' => $paymentInfo->spread_id,
            'click_id' =>$userInfo->click_id,
            'is_first' =>$is_first,
            'execution_num' =>$execution_num,
            'backhaul_dimension' =>$backhaulsettingInfo->backhaul_dimension,
            'reversal_mode' =>$backhaulsettingInfo->reversal_mode
        ]);
    }
    public function uploadPayment($userInfo,$paymentInfo,$spreadInfo){

        if(in_array($userInfo->id,self::$test_user)){

            $this->logger->info('测试用户进行：',[$userInfo->id]);
            return true;
        }

        $open_id = $userInfo->xc_open_id;
        $union_id = $userInfo->unionid;
        $clue_token = $userInfo->clue_token;
        $click_id =$userInfo->click_id;
        $spread_platform = $spreadInfo->spread_platform_id;
        try {

            if($spread_platform == 1){
                $params = [
                    "clue_token" => $clue_token,
                    "union_id"  => $union_id,
                    "open_id"  => $open_id,
                    "event_type"  => "2",
                    "props" => [
                        'pay_amount' => $paymentInfo->amount
                    ]
                ];
                $nonce = rand();
                $timestamp = time();
                $signature = $this->getSign($nonce,$timestamp);
                $linkUrl = self::$reportUrl.'?timestamp='.$timestamp.'&nonce='.$nonce.'&signature='.$signature;
                $this->logger->info('请求上报数据：'.PHP_EOL.var_export(['result' => $params], true));
                $this->logger->info('请求上报Url：'.$linkUrl);
                //开始上传
                $result  = $this->request($params, $linkUrl,'POST');
                if($result['status'] == 200 ){
                    $this->logger->info('调用上报接口成功 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                    //插入订单回传关联表
                    return true;
                }else{
                    $this->logger->error('调用上报接口失败 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                }
            }else if($spread_platform == 2){

                $params = [
//                    "callback" => $click_id,
//                    "event_type"  => "2",
//                    "props" => [
//                        'pay_amount' => $paymentInfo->amount
//                    ]
                ];
                $str = '{"pay_amount":"'.$paymentInfo->amount.'"}';
                $nonce = rand();
                $timestamp = time();
                $signature = $this->getSign($nonce,$timestamp);
                $linkUrl = self::$starReportUrl.'?callback='.$click_id.'&event_type=2&props='.urlencode($str);
                $this->logger->info('请求星图上报数据：'.PHP_EOL.var_export(['result' => $params], true));
                $this->logger->info('请求星图上报Url：'.$linkUrl);
                //开始上传
//                $result  = $this->request($params, $linkUrl,'GET');
                $result = $this->http_curl($linkUrl,'GET');
                if($result['code'] == 0 ){
                    $this->logger->info('调用星图上报接口成功 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                    //插入订单回传关联表
                    return true;
                }else{
                    $this->logger->error('调用星图上报接口失败 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                }
            }

        }catch (\Exception $e){

            $this->logger->error('请求回传|错误：' . $e->getLine() . '|' . $e->getMessage());
            return false;
        }

        return false;
    }
    public function getSign($nonce,$timestamp)
    {
        $token = self::$token;
        $collect = [$token, $nonce, $timestamp];
        //获取token
        usort($collect, 'strcmp');
        $signature = sha1(implode('', $collect));

        return $signature;
    }

    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method,string $access_token = null)
    {
        $client   = new Client([
            'timeout' => 3
        ]);
        $headers       = ['Content-Type' => 'application/json'];
        if(!empty($access_token)){
            $headers['access-token'] = $access_token;
        }

        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['json'] = $params;//json_encode($params,JSON_UNESCAPED_UNICODE);
        }
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }
    public function http_curl($url,$type='get',$res='json',$arr='')
    {
        //1.初始化curl
        $ch = curl_init();
        //2.设置curl的参数
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($type == 'post') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
        }
        curl_setopt($ch,CURLOPT_TIMEOUT,10);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        //3.采集
        $output = curl_exec($ch);

        //如果返回的值，是json格式，则转换成数组
        if ($res == 'json') {
            if (curl_errno($ch)) {
                //请求失败，返回错误信息
                $reutrn = curl_error($ch);
                curl_close($ch);
                return $reutrn;

            } else {
                $reutrn = json_decode($output, true);
                curl_close($ch);
                //请求成功
                return $reutrn;
            }
        }
    }
}